#pragma once
#include <iostream>
#include "Socket.hpp"
#include <pthread.h>
#include <functional>

using func_t = std::function<std::string(std::string &)>;

class HttpServer;

class ThreadData
{
public:
    ThreadData(HttpServer *tcp_this, Net_Work::Socket *sockp)
        : _this(tcp_this), _sockp(sockp)
    {
    }

public:
    HttpServer *_this;
    Net_Work::Socket *_sockp;
};

class HttpServer
{
public:
    HttpServer(uint16_t serverport, func_t handler_request)
        : _serverport(serverport), _listensock(new Net_Work::TcpSocket()), _handler_request(handler_request)
    {
        _listensock->BuildListensocketMethod(_serverport, Net_Work::backlog);
    }

    static void *Pthread_Run(void *args)
    {
        pthread_detach(pthread_self()); // 主线程和从线程进行分离
        ThreadData *td = static_cast<ThreadData *>(args);
        std::string http_request;

        // 1.进行读操作，并不关心结果如何
        if (td->_sockp->Recv(&http_request, 4096))
        {
            // 2.将读取的结果进行一系列的处理
            std::string http_response = td->_this->_handler_request(http_request);
            if (!http_response.empty())
            {
                // 3.进行写操作，将结果发送给客户端
                td->_sockp->Send(http_response);
            }
        }
        td->_sockp->CloseSocket();
        delete td->_sockp;
        delete td;
        return nullptr;
    }

    void Loop()
    {
        while (true)
        {
            std::string peerip;
            uint16_t peerport;
            Net_Work::Socket *newsock = _listensock->AcceptConnection(&peerip, &peerport);
            std::cout << "获取了一个新连接, sockfd: " << newsock->GetSockfd() << ", client info: "
                      << peerip << ":" << peerport << std::endl;
            pthread_t tid;
            ThreadData *td = new ThreadData(this, newsock);
            pthread_create(&tid, nullptr, Pthread_Run, td);
        }
    }

private:
    uint16_t _serverport;
    Net_Work::Socket *_listensock;

public:
    func_t _handler_request;
};